//
//  HOMTrampoline.h
//  HigherOrderMessaging
//
//  Created by Ofri Wolfus on 09/09/05.
//  Copyright 2005 Ofri Wolfus. All rights reserved.
//

#import <Foundation/NSProxy.h>

/*!
 * @header HOMTrampoline
 * HOMTrampoline defines the HOMTrampoline object which is a reuseable trampoline object for higer order messaging.
 * @copyright Created by Ofri Wolfus on 09/09/05. Copyright 2004-2005 Ofri Wolfus. All rights reserved.
 * @updated 2005-09-09
 * @version 0.1
 */


/*!
 * @class HOMTrampoline
 * @abstract A trampoline object that passes back any message it gets.
 * @discussion A trampoline will forward any message it receivs to it's target.
 * The selector of the trampoline will be called with an argument of the sent message (As an NSInvocation).
 * Once the trampoline had forwarded its invocation, it'll automatically release itself.
 * Each trampoline has a life time. The life time is the number of invocations that the trampoline can hold untill it passes them back to its target.
 * The default life time of a trampoline is 1 invocation. In this case, the selector of the trampoline will be something like this: <code>doSomethingWithInvocation:(NSInvocation *)invocation</code>.
 * The selector will be called with the 1 invocation that the trampoline holds.
 * If the life time of the trampoline is more then 1 invocation, the selector will be like this: <code>doSomethingElseWithInvocations:(NSArray *)invocations</code>.
 * The selector then will be passed with an array which holds all the invocations the trampoline holds by the order their messages where sent.
 */
@interface HOMTrampoline : NSProxy {
	id					target;
	SEL					selector;
	unsigned int		lifeTime;
	unsigned int		invocationsCount;
	NSMutableArray		*invocations;
}

/*!
 * @method trampolineWithTarget:selector:
 * @result Returns a new initialized (not autoreleased!) trampoline object with life time of 1 invocation.
 * @param aTarget is the target of the trampoline.
 * @param aSelector is the selector that gets sent to the target.
 */
+ (id)trampolineWithTarget:(id)aTarget selector:(SEL)aSelector;

/*!
 * @method trampolineWithTarget:selector:lifeTime:
 * @result Returns a new initialized (not autoreleased!) trampoline object.
 * @param aTarget The target of the trampoline.
 * @param aSelector The selector that gets sent to the target.
 * @param numberOfInvocations The number of the invocations that the trampoline will live.
 */
+ (id)trampolineWithTarget:(id)aTarget selector:(SEL)aSelector lifeTime:(unsigned int)numberOfInvocations;

/*!
 * @method initWithTarget:selector:
 * @result An initialized trampoline object with life time of 1 invocation.
 * @param aTarget is the target of the trampoline.
 * @param aSelector is the selector that gets sent to the target.
 */
- (id)initWithTarget:(id)aTarget selector:(SEL)aSelector;

/*!
 * @method initWithTarget:selector:
 * @result An initialized trampoline object.
 * @param aTarget is the target of the trampoline.
 * @param aSelector is the selector that gets sent to the target.
 * @param numberOfInvocations The number of the invocations that the trampoline will live.
 */
- (id)initWithTarget:(id)aTarget selector:(SEL)aSelector lifeTime:(unsigned int)numberOfInvocations;


/*!
 * @method setTarget:
 * @abstract Sets the target of the receiver.
 * The old target will be sent a release message, and the new one will be retaind.
 */
- (void)setTarget:(id)newTarget;

/*!
 * @method target
 * @abstract Returns the target of the receiver.
 */
- (id)target;

/*!
 * @method setSelector:
 * @abstract Sets the selector of the receiver.
 */
- (void)setSelector:(SEL)newSelector;

/*!
 * @method selector
 * @abstract Returns the selector of the receiver.
 */
- (SEL)selector;

@end

//=========================================================================================
//=========================================================================================
//=========================================================================================

//Methods compatibility for all isEqual methods
/*@interface HOMTrampoline (_HOMIsEqual)
- (id)isEqual:(id)object;
- (id)isEqualTo:(id)object;
- (id)isEqualToArray:(id)object;
- (id)isEqualToData:(id)object;
- (id)isEqualToDate:(id)object;
- (id)isEqualToDictionary:(id)object;
- (id)isEqualToHost:(id)object;
- (id)isEqualToIndexSet:(id)object;
- (id)isEqualToNumber:(id)object;
- (id)isEqualToSet:(id)object;
- (id)isEqualToString:(id)object;
- (id)isEqualToTimeZone:(id)object;
- (id)isEqualToValue:(id)object;
@end

//Methods compatibility for all -someValue methods
@interface HOMTrampoline (_HOMSomeValue)
- (id)pointerValue;
- (id)pointValue;
- (id)rangeValue;
- (id)rectValue;
- (id)sizeValue;
- (id)boolValue;
- (id)charValue;
- (id)decimalValue;
- (id)doubleValue;
- (id)floatValue;
- (id)intValue;
- (id)longLongValue;
- (id)longValue;
- (id)shortValue;
- (id)stringValue;
- (id)unsignedCharValue;
- (id)unsignedIntValue;
- (id)unsignedLongLongValue;
- (id)unsignedLongValue;
- (id)unsignedShortValue;
- (id)objectValue;
@end

//Methods compatibility for NSString
@interface HOMTrampoline (_HOMNSStringCompatibility)
- (id)hasPrefix:(NSString *)aString;
- (id)hasSuffix:(NSString *)aString;
- (id)isAbsolutePath;
- (id)rangeOfCharacterFromSet:(NSCharacterSet *)aSet;
- (id)rangeOfCharacterFromSet:(NSCharacterSet *)aSet options:(unsigned int)mask;
- (id)rangeOfCharacterFromSet:(NSCharacterSet *)aSet options:(unsigned int)mask range:(NSRange)aRange;
- (id)rangeOfComposedCharacterSequenceAtIndex:(unsigned)anIndex;
- (id)rangeOfString:(NSString *)aString;
- (id)rangeOfString:(NSString *)aString options:(unsigned)mask;
- (id)rangeOfString:(NSString *)subString options:(unsigned)mask range:(NSRange)aRange;
- (id)sizeWithAttributes:(NSDictionary *)attributes;
@end*/
